Purpose:

Runs survival analysis models using splicing cluster assignment and 1) single exon splicing burden index (SBI) or 2) KEGG Spliceosome GSVA scores as a predictor

Usage

Uses a wrapper function (survival_analysis) from utils folder.

Setup

Packages and functions

Load packages, set directory paths and call setup script

library(tidyverse)
library(survival)
library(ggpubr)
library(ggplot2)
library(patchwork)

root_dir <- rprojroot::find_root(rprojroot::has_dir(\.git\))

data_dir <- file.path(root_dir, \data\)
analysis_dir <- file.path(root_dir, \analyses\, \survival\)
input_dir <- file.path(analysis_dir, \results\)
results_dir <- file.path(analysis_dir, \results\)
plot_dir <- file.path(analysis_dir, \plots\)

# If the input and results directories do not exist, create it
if (!dir.exists(results_dir)) {
  dir.create(results_dir, recursive = TRUE)
}

source(file.path(analysis_dir, \util\, \survival_models.R\))

Set metadata and cluster assignment file paths

metadata_file <- file.path(input_dir, \splicing_indices_with_survival.tsv\)

cluster_file <- file.path(root_dir, \analyses\,
                          \sample-psi-clustering\, \results\,
                          \sample-cluster-metadata-top-5000-events-stranded.tsv\)

kegg_scores_stranded_file <- file.path(root_dir, \analyses\,
                          \sample-psi-clustering\, \results\,
                          \gsva_output_stranded.tsv\)

Wrangle data Add cluster assignment and spliceosome gsva scores to metadata and define column lgg_group (LGG or non_LGG)

metadata <- read_tsv(metadata_file)
clusters <- read_tsv(cluster_file) %>%
  dplyr::rename(Kids_First_Biospecimen_ID = sample_id)
gsva_scores <- read_tsv(kegg_scores_stranded_file) %>%
  dplyr::filter(geneset == \KEGG_SPLICEOSOME\) %>%
  dplyr::rename(spliceosome_gsva_score = score)
# how many clusters?
n_clust <- length(unique(clusters$cluster))

metadata <- metadata %>%
  right_join(clusters %>% dplyr::select(Kids_First_Biospecimen_ID,
                                       cluster)) %>%
  left_join(gsva_scores %>% dplyr::select(sample_id,
                                          spliceosome_gsva_score),
            by = c(\Kids_First_Biospecimen_ID\ = \sample_id\)) %>% 
  dplyr::mutate(cluster = glue::glue(\Cluster {cluster}\)) %>%
  dplyr::mutate(cluster = fct_relevel(cluster,
                                               paste0(\Cluster \, 1:n_clust))) %>%
  dplyr::mutate(lgg_group = case_when(
    plot_group == \Low-grade glioma\ ~ \LGG\,
    TRUE ~ \non-LGG\
  )) %>%
  dplyr::mutate(SBI = SI_Total * 10) %>%
  dplyr::mutate(age_at_diagnosis_years = age_at_diagnosis_days/365.25)

Generate coxph models including extent of tumor resection, lgg group, and cluster assignment and SBI as covariates

add_model_os <- fit_save_model(metadata[!metadata$extent_of_tumor_resection %in% c(\Not Reported\, \Unavailable\),],
                              terms = \extent_of_tumor_resection+lgg_group+cluster+age_at_diagnosis_years+SBI\,
                               file.path(results_dir, \cox_OS_additive_terms_resection_lgg_group_cluster_SBI.RDS\),
                               \multivariate\,
                               years_col = \OS_years\,
                               status_col = \OS_status\)

forest_os <- plotForest(readRDS(file.path(results_dir, \cox_OS_additive_terms_resection_lgg_group_cluster_SBI.RDS\)))

forest_os

ggsave(file.path(plot_dir, \forest_add_OS_resection_lgg_group_cluster_assignment_SBI.pdf\),
       forest_os,
       width = 10, height = 6, units = \in\,
       device = \pdf\)

add_model_efs <- fit_save_model(metadata[!metadata$extent_of_tumor_resection %in% c(\Not Reported\, \Unavailable\),],
                              terms = \extent_of_tumor_resection+lgg_group+cluster+age_at_diagnosis_years+SBI\,
                               file.path(results_dir, \cox_EFS_additive_terms_resection_lgg_group_cluster_SBI.RDS\),
                               \multivariate\,
                               years_col = \EFS_years\,
                               status_col = \EFS_status\)

forest_efs <- plotForest(readRDS(file.path(results_dir, \cox_EFS_additive_terms_resection_lgg_group_cluster_SBI.RDS\)))

forest_efs

ggsave(file.path(plot_dir, \forest_add_EFS_resection_lgg_group_cluster_assignment_SBI.pdf\),
       forest_efs,
       width = 10, height = 6, units = \in\,
       device = \pdf\)

repeat analysis, replacing SBI with KEGG spliceosome gsva score

add_model_os <- fit_save_model(metadata[!metadata$extent_of_tumor_resection %in% c(\Not Reported\, \Unavailable\),],
                              terms = \extent_of_tumor_resection+lgg_group+cluster+age_at_diagnosis_years+spliceosome_gsva_score\,
                               file.path(results_dir, \cox_OS_additive_terms_resection_lgg_group_cluster_spliceosome_score.RDS\),
                               \multivariate\,
                               years_col = \OS_years\,
                               status_col = \OS_status\)

forest_os <- plotForest(readRDS(file.path(results_dir, \cox_OS_additive_terms_resection_lgg_group_cluster_spliceosome_score.RDS\)))

forest_os

ggsave(file.path(plot_dir, \forest_add_OS_resection_lgg_group_cluster_assignment_spliceosome_score.pdf\),
       forest_os,
       width = 10, height = 6, units = \in\,
       device = \pdf\)
models <- c(\spliceosome_gsva_score\, \SBI\)

for (each in models) {
  int_model_efs <- fit_save_model(metadata[!metadata$extent_of_tumor_resection %in% c(\Not Reported\, \Unavailable\),],
                                terms = paste0(\extent_of_tumor_resection+lgg_group+cluster*\, each, \+age_at_diagnosis_years\),
                                 file.path(results_dir, paste0(\cox_EFS_interaction_terms_resection_lgg_group_cluster_\, each, \.RDS\)),
                                 \multivariate\,
                                 years_col = \EFS_years\,
                                 status_col = \EFS_status\)
  
  int_forest_efs <- plotForest(readRDS(file.path(results_dir, paste0(\cox_EFS_interaction_terms_resection_lgg_group_cluster_\, each, \.RDS\))))
  
  int_forest_efs
  
  ggsave(file.path(plot_dir, paste0(\forest_int_EFS_resection_lgg_group_cluster_assignment_\, each, \.pdf\)),
         int_forest_efs,
         width = 10, height = 6, units = \in\,
         device = \pdf\)

  int_model_os <- fit_save_model(metadata[!metadata$extent_of_tumor_resection %in% c(\Not Reported\, \Unavailable\),],
                                terms = paste0(\extent_of_tumor_resection+lgg_group+cluster*\, each, \+age_at_diagnosis_years\),
                                 file.path(results_dir, paste0(\cox_OS_interaction_terms_resection_lgg_group_cluster_\, each, \.RDS\)),
                                 \multivariate\,
                                 years_col = \OS_years\,
                                 status_col = \OS_status\)
  
  int_forest_os <- plotForest(readRDS(file.path(results_dir, paste0(\cox_OS_interaction_terms_resection_lgg_group_cluster_\, each, \.RDS\))))
  
  int_forest_os
  
  ggsave(file.path(plot_dir, paste0(\forest_int_OS_resection_lgg_group_cluster_assignment_\, each, \.pdf\)),
         int_forest_os,
         width = 10, height = 6, units = \in\,
         device = \pdf\)
  
}

add_model_efs <- fit_save_model(metadata[!metadata$extent_of_tumor_resection %in% c(\Not Reported\, \Unavailable\),],
                              terms = \extent_of_tumor_resection+lgg_group+cluster+age_at_diagnosis_years+spliceosome_gsva_score\,
                               file.path(results_dir, \cox_EFS_additive_terms_resection_lgg_group_cluster_spliceosome_score.RDS\),
                               \multivariate\,
                               years_col = \EFS_years\,
                               status_col = \EFS_status\)

forest_efs <- plotForest(readRDS(file.path(results_dir, \cox_EFS_additive_terms_resection_lgg_group_cluster_spliceosome_score.RDS\)))

forest_efs

ggsave(file.path(plot_dir, \forest_add_EFS_resection_lgg_group_cluster_assignment_spliceosome_score.pdf\),
       forest_efs,
       width = 10, height = 6, units = \in\,
       device = \pdf\)

Subset metadata for LGG, and only include clusters with >= 10 samples

lgg <- metadata %>%
  dplyr::filter(plot_group == \Low-grade glioma\) %>%
  dplyr::mutate(cluster = factor(cluster)) %>%
  dplyr::mutate(mol_sub_group = fct_relevel(mol_sub_group, \Wildtype\, after = 0))

retain_clusters_lgg <- lgg %>%
  dplyr::count(cluster) %>%
  filter(n >= 10) %>%
  pull(cluster)

lgg <- lgg %>%
  filter(cluster %in% retain_clusters_lgg) %>%
    dplyr::mutate(cluster = factor(cluster))

Generate coxph models including covariates extent_of_tumor_resection, mol_sub_group, cluster, and SBI and plot

# identify LGG clusters
lgg_clusters <- metadata %>%
  filter(lgg_group == \LGG\) %>%
  mutate(cluster = as.integer(gsub(\cluster\, \\, cluster))) %>%
  pull(cluster) %>%
  sort() %>%
  unique()
add_model_lgg_efs <- fit_save_model(lgg[!lgg$cluster %in% lgg_clusters & !lgg$extent_of_tumor_resection %in% c(\Not Reported\, \Unavailable\),],
                              terms = \extent_of_tumor_resection+mol_sub_group+cluster+age_at_diagnosis_years+SBI\,
                               file.path(results_dir, \cox_lgg_EFS_additive_terms_resection_subtype_cluster_SBI.RDS\),
                               \multivariate\,
                               years_col = \EFS_years\,
                               status_col = \EFS_status\)
forest_lgg_efs <- plotForest(readRDS(file.path(results_dir, \cox_lgg_EFS_additive_terms_resection_subtype_cluster_SBI.RDS\)))

forest_lgg_efs

ggsave(file.path(plot_dir, \forest_add_EFS_LGG_resection_subtype_cluster_assignment_SBI.pdf\),
       forest_lgg_efs,
       width = 10, height = 6, units = \in\,
       device = \pdf\)

repeat analysis replacing SBI with spliceosome_gsva_score

add_model_lgg_efs <- fit_save_model(lgg[!lgg$cluster %in% lgg_clusters & !lgg$extent_of_tumor_resection %in% c(\Not Reported\, \Unavailable\),],
                              terms = \extent_of_tumor_resection+mol_sub_group+cluster+age_at_diagnosis_years+spliceosome_gsva_score\,
                               file.path(results_dir, \cox_lgg_EFS_additive_terms_resection_subtype_cluster_spliceosome_score.RDS\),
                               \multivariate\,
                               years_col = \EFS_years\,
                               status_col = \EFS_status\)
forest_lgg_efs <- plotForest(readRDS(file.path(results_dir, \cox_lgg_EFS_additive_terms_resection_subtype_cluster_spliceosome_score.RDS\)))

forest_lgg_efs

ggsave(file.path(plot_dir, \forest_add_EFS_LGG_resection_subtype_cluster_assignment_spliceosome_score.pdf\),
       forest_lgg_efs,
       width = 10, height = 6, units = \in\,
       device = \pdf\)

Subset metadata for HGG and retain cluster with n >= 10

hgg <- metadata %>%
  dplyr::filter(plot_group %in% c(\Other high-grade glioma\, \Diffuse midline glioma\)) %>%
  dplyr::mutate(cluster = factor(cluster)) %>%
  dplyr::mutate(mol_sub_group = fct_relevel(mol_sub_group, \HGG

Generate HGG KM models with spliceosome_group as covariate

# Generate kaplan meier survival models for OS and EFS, and save outputs
hgg_kap_os <- survival_analysis(
  metadata  = hgg %>% dplyr::filter(!is.na(spliceosome_group)),
  ind_var = \spliceosome_group\,
  test = \kap.meier\,
  metadata_sample_col = \Kids_First_Biospecimen_ID\,
  days_col = \OS_days\,
  status_col = \OS_status\
)
readr::write_rds(hgg_kap_os,
                 file.path(results_dir, \logrank_hgg_OS_splice_group.RDS\))

hgg_kap_efs <- survival_analysis(
  metadata  = hgg %>% dplyr::filter(!is.na(spliceosome_group)),
  ind_var = \spliceosome_group\,
  test = \kap.meier\,
  metadata_sample_col = \Kids_First_Biospecimen_ID\,
  days_col = \EFS_days\,
  status_col = \EFS_status\
)
readr::write_rds(hgg_kap_efs,
                 file.path(results_dir, \logrank_hgg_EFS_splice_group.RDS\))

Generate KM plots

km_hgg_os_plot <- plotKM(model = hgg_kap_os,
                    variable = \spliceosome_group\,
                    combined = F, 
                    title = \HGG
ggsave(file.path(plot_dir, \km_hgg_OS_spliceosome_score.pdf\),
       km_hgg_os_plot,
       width = 9, height = 5, units = \in\,
       device = \pdf\)
km_hgg_efs_plot <- plotKM(model = hgg_kap_efs,
                    variable = \spliceosome_group\,
                    combined = F, 
                    title = \HGG
ggsave(file.path(plot_dir, \km_hgg_EFS_spliceosome_score.pdf\), 
       km_hgg_efs_plot,
       width = 9, height = 5, units = \in\,
       device = \pdf\)

Generate coxph models for HGG including covariates mol_sub_group cluster, and SBI, and plot

add_model_hgg_os <- fit_save_model(hgg,
                              terms = \mol_sub_group+age_at_diagnosis_years+SBI\,
                               file.path(results_dir, \cox_hgg_OS_additive_terms_subtype_cluster_SBI.RDS\),
                               \multivariate\,
                               years_col = \OS_years\,
                               status_col = \OS_status\)
forest_hgg_os <- plotForest(readRDS(file.path(results_dir, \cox_hgg_OS_additive_terms_subtype_cluster_SBI.RDS\)))

forest_hgg_os

ggsave(file.path(plot_dir, \forest_add_OS_HGG_subtype_cluster_assignment_SBI.pdf\),
       forest_hgg_os,
       width = 9, height = 5, units = \in\,
       device = \pdf\)

add_model_hgg_efs <- fit_save_model(hgg,
                              terms = \mol_sub_group+age_at_diagnosis_years+SBI\,
                               file.path(results_dir, \cox_hgg_EFS_additive_terms_subtype_cluster_SBI.RDS\),
                               \multivariate\,
                               years_col = \EFS_years\,
                               status_col = \EFS_status\)

forest_hgg_efs <- plotForest(readRDS(file.path(results_dir, \cox_hgg_EFS_additive_terms_subtype_cluster_SBI.RDS\)))

ggsave(file.path(plot_dir, \forest_add_EFS_HGG_subtype_cluster_assignment_SBI.pdf\),
       forest_hgg_efs,
       width = 9, height = 5, units = \in\,
       device = \pdf\)

Repeat analysis replacing SBI with spliceosome_gsva_score

add_model_hgg_os <- fit_save_model(hgg,
                              terms = \mol_sub_group+age_at_diagnosis_years+spliceosome_gsva_score\,
                               file.path(results_dir, \cox_hgg_OS_additive_terms_subtype_cluster_spliceosome_score.RDS\),
                               \multivariate\,
                               years_col = \OS_years\,
                               status_col = \OS_status\)
forest_hgg_os <- plotForest(readRDS(file.path(results_dir, \cox_hgg_OS_additive_terms_subtype_cluster_spliceosome_score.RDS\)))

forest_hgg_os

ggsave(file.path(plot_dir, \forest_add_OS_HGG_subtype_cluster_assignment_spliceosome_score.pdf\),
       forest_hgg_os,
       width = 9, height = 5, units = \in\,
       device = \pdf\)

add_model_hgg_efs <- fit_save_model(hgg,
                              terms = \mol_sub_group+age_at_diagnosis_years+spliceosome_gsva_score\,
                               file.path(results_dir, \cox_hgg_EFS_additive_terms_subtype_cluster_spliceosome_score.RDS\),
                               \multivariate\,
                               years_col = \EFS_years\,
                               status_col = \EFS_status\)

forest_hgg_efs <- plotForest(readRDS(file.path(results_dir, \cox_hgg_EFS_additive_terms_subtype_cluster_spliceosome_score.RDS\)))

ggsave(file.path(plot_dir, \forest_add_EFS_HGG_subtype_cluster_assignment_spliceosome_score.pdf\),
       forest_hgg_efs,
       width = 9, height = 5, units = \in\,
       device = \pdf\)

Filter for cluster 7

cluster7_df <- metadata %>%
  dplyr::filter(cluster == \Cluster 7\,
                !is.na(EFS_days)) %>%
  dplyr::mutate(SI_group = case_when(
      SBI > summary(SBI)[\3rd Qu.\] ~ \High SBI\,
      SBI < summary(SBI)[\1st Qu.\] ~ \Low SBI\,
      TRUE ~ NA_character_
    )) %>%
  dplyr::mutate(spliceosome_group = case_when(
      spliceosome_gsva_score > summary(spliceosome_gsva_score)[\3rd Qu.\] ~ \Splice GSVA 4th Q\,
      spliceosome_gsva_score > summary(spliceosome_gsva_score)[\Median\] ~ \Splice GSVA 3rd Q\,
      spliceosome_gsva_score > summary(spliceosome_gsva_score)[\1st Qu.\] ~ \Splice GSVA 2nd Q\,
      TRUE ~ \Splice GSVA 1st Q\
    )) %>%
  dplyr::mutate(SI_group = fct_relevel(SI_group,
                                                 c(\High SBI\, \Low SBI\))) %>%
  dplyr::mutate(spliceosome_group = fct_relevel(spliceosome_group,
                                                 c(\Splice GSVA 1st Q\, 
                                                   \Splice GSVA 2nd Q\, 
                                                   \Splice GSVA 3rd Q\,
                                                   \Splice GSVA 4th Q\)))

Generate KM models with SI_group as covariate

# Generate kaplan meier survival models for OS and EFS, and save outputs
c7_si_kap_os <- survival_analysis(
  metadata  = cluster7_df %>% dplyr::filter(!is.na(SI_group)),
  ind_var = \SI_group\,
  test = \kap.meier\,
  metadata_sample_col = \Kids_First_Biospecimen_ID\,
  days_col = \OS_days\,
  status_col = \OS_status\
)
readr::write_rds(c7_si_kap_os,
                 file.path(results_dir, \logrank_cluster7_OS_SBI.RDS\))

c7_si_kap_efs <- survival_analysis(
  metadata  = cluster7_df %>% dplyr::filter(!is.na(SI_group)),
  ind_var = \SI_group\,
  test = \kap.meier\,
  metadata_sample_col = \Kids_First_Biospecimen_ID\,
  days_col = \EFS_days\,
  status_col = \EFS_status\
)
readr::write_rds(c7_si_kap_efs,
                 file.path(results_dir, \logrank_cluster7_EFS_SBI.RDS\))

Generate Cluster 7 KM SI_group plots

km_c7_si_os_plot <- plotKM(model = c7_si_kap_os,
                    variable = \SI_group\,
                    combined = F, 
                    title = \Cluster 7
ggsave(file.path(plot_dir, \km_cluster7_OS_sbi_group.pdf\),
       km_c7_si_os_plot,
       width = 8, height = 5, units = \in\,
       device = \pdf\)
km_c7_si_efs_plot <- plotKM(model = c7_si_kap_efs,
                    variable = \SI_group\,
                    combined = F, 
                    title = \Cluster 7
ggsave(file.path(plot_dir, \km_cluster7_EFS_sbi_group.pdf\), 
       km_c7_si_efs_plot,
       width = 8, height = 5, units = \in\,
       device = \pdf\)

Generate KM models with spliceosome_group as covariate

# Generate kaplan meier survival models for OS and EFS, and save outputs
c7_splice_kap_os <- survival_analysis(
  metadata  = cluster7_df %>% 
    dplyr::filter(spliceosome_group %in% c(\Splice GSVA 4th Q\, \Splice GSVA 1st Q\)) %>%
    dplyr::mutate(spliceosome_group = factor(spliceosome_group,
                                                  levels = c(\Splice GSVA 1st Q\, \Splice GSVA 4th Q\))),
  ind_var = \spliceosome_group\,
  test = \kap.meier\,
  metadata_sample_col = \Kids_First_Biospecimen_ID\,
  days_col = \OS_days\,
  status_col = \OS_status\
)
readr::write_rds(c7_splice_kap_os,
                 file.path(results_dir, \logrank_cluster7_OS_splice_group.RDS\))

c7_splice_kap_efs <- survival_analysis(
  metadata  = cluster7_df %>% 
    dplyr::filter(spliceosome_group %in% c(\Splice GSVA 4th Q\, \Splice GSVA 1st Q\)) %>%
    dplyr::mutate(spliceosome_group = factor(spliceosome_group,
                                                  levels = c(\Splice GSVA 1st Q\, \Splice GSVA 4th Q\))),
  ind_var = \spliceosome_group\,
  test = \kap.meier\,
  metadata_sample_col = \Kids_First_Biospecimen_ID\,
  days_col = \EFS_days\,
  status_col = \EFS_status\
)
readr::write_rds(c7_splice_kap_efs,
                 file.path(results_dir, \logrank_cluster7_EFS_splice_group.RDS\))

Generate Cluster 7 KM spliceosome_group plots

km_c7_splice_os_plot <- plotKM(model = c7_splice_kap_os,
                    variable = \spliceosome_group\,
                    combined = F, 
                    title = \Cluster 7
ggsave(file.path(plot_dir, \km_cluster7_OS_splice_group.pdf\),
       km_c7_splice_os_plot,
       width = 9, height = 5, units = \in\,
       device = \pdf\)
km_c7_splice_efs_plot <- plotKM(model = c7_splice_kap_efs,
                    variable = \spliceosome_group\,
                    combined = F, 
                    title = \Cluster 7
ggsave(file.path(plot_dir, \km_cluster7_EFS_splice_group.pdf\), 
       km_c7_splice_efs_plot,
       width = 9, height = 5, units = \in\,
       device = \pdf\)

Assess EFS and OS by SBI or spliceosome GSVA score in multivariate models and generate forest plots

add_model_c7_efs <- fit_save_model(cluster7_df %>% 
                                      dplyr::filter(extent_of_tumor_resection != \Unavailable\,
                                                    spliceosome_group %in% c(\Splice GSVA 4th Q\, \Splice GSVA 1st Q\)) %>%
                                      dplyr::mutate(plot_group = fct_relevel(plot_group, \Low-grade glioma\, after = 0)),
                              terms = \extent_of_tumor_resection+age_at_diagnosis_years+plot_group+spliceosome_group\,
                               file.path(results_dir, \cox_hgg_EFS_additive_terms_subtype_cluster_spliceosome_score.RDS\),
                               \multivariate\,
                               years_col = \EFS_years\,
                               status_col = \EFS_status\)
forest_c7_spliceosome_efs <- plotForest(readRDS(file.path(results_dir, \cox_hgg_EFS_additive_terms_subtype_cluster_spliceosome_score.RDS\)))

ggsave(file.path(plot_dir, \forest_add_EFS_cluster7_histology_resection_spliceosome_group.pdf\),
       forest_c7_spliceosome_efs,
       width = 9, height = 4, units = \in\,
       device = \pdf\)

add_model_c7_os <- fit_save_model(cluster7_df %>% 
                                    dplyr::filter(!extent_of_tumor_resection %in% c(\Not Reported\, \Unavailable\)) %>%
                                    dplyr::mutate(plot_group = fct_relevel(plot_group, \Low-grade glioma\, after = 0)),
                              terms = \extent_of_tumor_resection+age_at_diagnosis_years+plot_group+SBI\,
                               file.path(results_dir, \cox_hgg_OS_additive_terms_subtype_cluster_si_group.RDS\),
                               \multivariate\,
                               years_col = \OS_years\,
                               status_col = \OS_status\)
forest_c7_si_os <- plotForest(readRDS(file.path(results_dir, \cox_hgg_OS_additive_terms_subtype_cluster_si_group.RDS\)))

ggsave(file.path(plot_dir, \forest_add_OS_cluster7_histology_resection_si.pdf\),
       forest_c7_si_os,
       width = 9, height = 4, units = \in\,
       device = \pdf\)

Print session info

sessionInfo()
R version 4.4.0 (2024-04-24)
Platform: x86_64-pc-linux-gnu
Running under: Ubuntu 22.04.4 LTS

Matrix products: default
BLAS:   /usr/lib/x86_64-linux-gnu/openblas-pthread/libblas.so.3 
LAPACK: /usr/lib/x86_64-linux-gnu/openblas-pthread/libopenblasp-r0.3.20.so;  LAPACK version 3.10.0

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
 [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
 [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
 [9] LC_ADDRESS=C               LC_TELEPHONE=C            
[11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

time zone: Etc/UTC
tzcode source: system (glibc)

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
 [1] gtools_3.9.5    survminer_0.4.9 patchwork_1.2.0 ggpubr_0.6.0   
 [5] survival_3.7-0  lubridate_1.9.4 forcats_1.0.1   stringr_1.6.0  
 [9] dplyr_1.1.4     purrr_1.2.0     readr_2.1.6     tidyr_1.3.1    
[13] tibble_3.3.0    ggplot2_4.0.1   tidyverse_2.0.0

loaded via a namespace (and not attached):
 [1] gtable_0.3.6       xfun_0.54          bslib_0.9.0        rstatix_0.7.2     
 [5] lattice_0.22-7     tzdb_0.5.0         vctrs_0.6.5        tools_4.4.0       
 [9] generics_0.1.4     parallel_4.4.0     pkgconfig_2.0.3    Matrix_1.7-4      
[13] data.table_1.17.8  RColorBrewer_1.1-3 S7_0.2.1           lifecycle_1.0.4   
[17] compiler_4.4.0     farver_2.1.2       textshaping_1.0.4  carData_3.0-5     
[21] colorblindr_0.1.0  htmltools_0.5.8.1  sass_0.4.10        yaml_2.3.10       
[25] crayon_1.5.3       pillar_1.11.1      car_3.1-2          jquerylib_0.1.4   
[29] cachem_1.1.0       abind_1.4-5        km.ci_0.5-6        commonmark_2.0.0  
[33] tidyselect_1.2.1   digest_0.6.39      stringi_1.8.7      labeling_0.4.3    
[37] splines_4.4.0      cowplot_1.1.3      rprojroot_2.1.1    fastmap_1.2.0     
[41] grid_4.4.0         colorspace_2.1-2   cli_3.6.5          magrittr_2.0.4    
[45] broom_1.0.10       withr_3.0.2        scales_1.4.0       backports_1.5.0   
[49] bit64_4.6.0-1      timechange_0.3.0   rmarkdown_2.30     ggtext_0.1.2      
[53] bit_4.6.0          gridExtra_2.3      ggsignif_0.6.4     ragg_1.5.0        
[57] zoo_1.8-12         hms_1.1.4          evaluate_1.0.5     knitr_1.50        
[61] KMsurv_0.1-5       markdown_1.13      survMisc_0.5.6     rlang_1.1.6       
[65] Rcpp_1.1.0         gridtext_0.1.5     xtable_1.8-4       glue_1.8.0        
[69] xml2_1.5.0         vroom_1.6.6        jsonlite_2.0.0     R6_2.6.1          
[73] systemfonts_1.3.1 
LS0tCnRpdGxlOiAiUnVuIExHRyBhbmQgSEdHIHN1cnZpdmFsIGJ5IHNwbGljaW5nIGNsdXN0ZXIgYXNzaWdubWVudCBhbmQgc3BsaWNpbmcgYnVyZGVuIgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IFRSVUUKICAgIHRvY19mbG9hdDogVFJVRQphdXRob3I6IFJ5YW4gQ29yYmV0dApkYXRlOiAyMDI0CnBhcmFtczoKICBwbG90X2NpOiBUUlVFCi0tLQoKKipQdXJwb3NlOioqIAoKUnVucyBzdXJ2aXZhbCBhbmFseXNpcyBtb2RlbHMgdXNpbmcgc3BsaWNpbmcgY2x1c3RlciBhc3NpZ25tZW50IGFuZCAxKSBzaW5nbGUgZXhvbiBzcGxpY2luZyBidXJkZW4gaW5kZXggKFNCSSkgb3IgMikgS0VHRyBTcGxpY2Vvc29tZSBHU1ZBIHNjb3JlcyBhcyBhIHByZWRpY3RvcgoKIyMgVXNhZ2UgCgpVc2VzIGEgd3JhcHBlciBmdW5jdGlvbiAoYHN1cnZpdmFsX2FuYWx5c2lzYCkgZnJvbSB1dGlscyBmb2xkZXIuIAoKIyMgU2V0dXAKCiMjIyMgUGFja2FnZXMgYW5kIGZ1bmN0aW9ucwoKTG9hZCBwYWNrYWdlcywgc2V0IGRpcmVjdG9yeSBwYXRocyBhbmQgY2FsbCBzZXR1cCBzY3JpcHQKCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShzdXJ2aXZhbCkKbGlicmFyeShnZ3B1YnIpCmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeShwYXRjaHdvcmspCgpyb290X2RpciA8LSBycHJvanJvb3Q6OmZpbmRfcm9vdChycHJvanJvb3Q6Omhhc19kaXIoIi5naXQiKSkKCmRhdGFfZGlyIDwtIGZpbGUucGF0aChyb290X2RpciwgImRhdGEiKQphbmFseXNpc19kaXIgPC0gZmlsZS5wYXRoKHJvb3RfZGlyLCAiYW5hbHlzZXMiLCAic3Vydml2YWwiKQppbnB1dF9kaXIgPC0gZmlsZS5wYXRoKGFuYWx5c2lzX2RpciwgInJlc3VsdHMiKQpyZXN1bHRzX2RpciA8LSBmaWxlLnBhdGgoYW5hbHlzaXNfZGlyLCAicmVzdWx0cyIpCnBsb3RfZGlyIDwtIGZpbGUucGF0aChhbmFseXNpc19kaXIsICJwbG90cyIpCgojIElmIHRoZSBpbnB1dCBhbmQgcmVzdWx0cyBkaXJlY3RvcmllcyBkbyBub3QgZXhpc3QsIGNyZWF0ZSBpdAppZiAoIWRpci5leGlzdHMocmVzdWx0c19kaXIpKSB7CiAgZGlyLmNyZWF0ZShyZXN1bHRzX2RpciwgcmVjdXJzaXZlID0gVFJVRSkKfQoKc291cmNlKGZpbGUucGF0aChhbmFseXNpc19kaXIsICJ1dGlsIiwgInN1cnZpdmFsX21vZGVscy5SIikpCmBgYAoKU2V0IG1ldGFkYXRhIGFuZCBjbHVzdGVyIGFzc2lnbm1lbnQgZmlsZSBwYXRocwoKYGBge3Igc2V0IHBhdGhzfQptZXRhZGF0YV9maWxlIDwtIGZpbGUucGF0aChpbnB1dF9kaXIsICJzcGxpY2luZ19pbmRpY2VzX3dpdGhfc3Vydml2YWwudHN2IikKCmNsdXN0ZXJfZmlsZSA8LSBmaWxlLnBhdGgocm9vdF9kaXIsICJhbmFseXNlcyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgInNhbXBsZS1wc2ktY2x1c3RlcmluZyIsICJyZXN1bHRzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAic2FtcGxlLWNsdXN0ZXItbWV0YWRhdGEtdG9wLTUwMDAtZXZlbnRzLXN0cmFuZGVkLnRzdiIpCgprZWdnX3Njb3Jlc19zdHJhbmRlZF9maWxlIDwtIGZpbGUucGF0aChyb290X2RpciwgImFuYWx5c2VzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAic2FtcGxlLXBzaS1jbHVzdGVyaW5nIiwgInJlc3VsdHMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICJnc3ZhX291dHB1dF9zdHJhbmRlZC50c3YiKQpgYGAKCldyYW5nbGUgZGF0YSAKQWRkIGNsdXN0ZXIgYXNzaWdubWVudCBhbmQgc3BsaWNlb3NvbWUgZ3N2YSBzY29yZXMgdG8gYG1ldGFkYXRhYCBhbmQgZGVmaW5lIGNvbHVtbiBgbGdnX2dyb3VwYCAoTEdHIG9yIG5vbl9MR0cpCgpgYGB7cn0KbWV0YWRhdGEgPC0gcmVhZF90c3YobWV0YWRhdGFfZmlsZSkKCmNsdXN0ZXJzIDwtIHJlYWRfdHN2KGNsdXN0ZXJfZmlsZSkgJT4lCiAgZHBseXI6OnJlbmFtZShLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lEID0gc2FtcGxlX2lkKQoKZ3N2YV9zY29yZXMgPC0gcmVhZF90c3Yoa2VnZ19zY29yZXNfc3RyYW5kZWRfZmlsZSkgJT4lCiAgZHBseXI6OmZpbHRlcihnZW5lc2V0ID09ICJLRUdHX1NQTElDRU9TT01FIikgJT4lCiAgZHBseXI6OnJlbmFtZShzcGxpY2Vvc29tZV9nc3ZhX3Njb3JlID0gc2NvcmUpCgojIGhvdyBtYW55IGNsdXN0ZXJzPwpuX2NsdXN0IDwtIGxlbmd0aCh1bmlxdWUoY2x1c3RlcnMkY2x1c3RlcikpCgptZXRhZGF0YSA8LSBtZXRhZGF0YSAlPiUKICByaWdodF9qb2luKGNsdXN0ZXJzICU+JSBkcGx5cjo6c2VsZWN0KEtpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNsdXN0ZXIpKSAlPiUKICBsZWZ0X2pvaW4oZ3N2YV9zY29yZXMgJT4lIGRwbHlyOjpzZWxlY3Qoc2FtcGxlX2lkLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzcGxpY2Vvc29tZV9nc3ZhX3Njb3JlKSwKICAgICAgICAgICAgYnkgPSBjKCJLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lEIiA9ICJzYW1wbGVfaWQiKSkgJT4lIAogIGRwbHlyOjptdXRhdGUoY2x1c3RlciA9IGdsdWU6OmdsdWUoIkNsdXN0ZXIge2NsdXN0ZXJ9IikpICU+JQogIGRwbHlyOjptdXRhdGUoY2x1c3RlciA9IGZjdF9yZWxldmVsKGNsdXN0ZXIsIHBhc3RlMCgiQ2x1c3RlciAiLCAxOm5fY2x1c3QpKSkgJT4lCiAgZHBseXI6Om11dGF0ZShsZ2dfZ3JvdXAgPSBjYXNlX3doZW4oCiAgICBwbG90X2dyb3VwID09ICJMb3ctZ3JhZGUgZ2xpb21hIiB+ICJMR0ciLAogICAgVFJVRSB+ICJub24tTEdHIgogICkpICU+JQogIGRwbHlyOjptdXRhdGUoU0JJID0gU0lfVG90YWwgKiAxMCkgJT4lCiAgZHBseXI6Om11dGF0ZShhZ2VfYXRfZGlhZ25vc2lzX3llYXJzID0gYWdlX2F0X2RpYWdub3Npc19kYXlzLzM2NS4yNSkKYGBgCgpHZW5lcmF0ZSBjb3hwaCBtb2RlbHMgaW5jbHVkaW5nIGV4dGVudCBvZiB0dW1vciByZXNlY3Rpb24sIGxnZyBncm91cCwgYW5kIGNsdXN0ZXIgYXNzaWdubWVudCBhbmQgU0JJIGFzIGNvdmFyaWF0ZXMKCmBgYHtyfQphZGRfbW9kZWxfb3MgPC0gZml0X3NhdmVfbW9kZWwobWV0YWRhdGFbIW1ldGFkYXRhJGV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24gJWluJSBjKCJOb3QgUmVwb3J0ZWQiLCAiVW5hdmFpbGFibGUiKSxdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXJtcyA9ICJleHRlbnRfb2ZfdHVtb3JfcmVzZWN0aW9uK2xnZ19ncm91cCtjbHVzdGVyK2FnZV9hdF9kaWFnbm9zaXNfeWVhcnMrU0JJIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUucGF0aChyZXN1bHRzX2RpciwgImNveF9PU19hZGRpdGl2ZV90ZXJtc19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfU0JJLlJEUyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm11bHRpdmFyaWF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyc19jb2wgPSAiT1NfeWVhcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzX2NvbCA9ICJPU19zdGF0dXMiKQoKZm9yZXN0X29zIDwtIHBsb3RGb3Jlc3QocmVhZFJEUyhmaWxlLnBhdGgocmVzdWx0c19kaXIsICJjb3hfT1NfYWRkaXRpdmVfdGVybXNfcmVzZWN0aW9uX2xnZ19ncm91cF9jbHVzdGVyX1NCSS5SRFMiKSkpCgpmb3Jlc3Rfb3MKCmdnc2F2ZShmaWxlLnBhdGgocGxvdF9kaXIsICJmb3Jlc3RfYWRkX09TX3Jlc2VjdGlvbl9sZ2dfZ3JvdXBfY2x1c3Rlcl9hc3NpZ25tZW50X1NCSS5wZGYiKSwKICAgICAgIGZvcmVzdF9vcywKICAgICAgIHdpZHRoID0gMTAsIGhlaWdodCA9IDYsIHVuaXRzID0gImluIiwKICAgICAgIGRldmljZSA9ICJwZGYiKQoKYWRkX21vZGVsX2VmcyA8LSBmaXRfc2F2ZV9tb2RlbChtZXRhZGF0YVshbWV0YWRhdGEkZXh0ZW50X29mX3R1bW9yX3Jlc2VjdGlvbiAlaW4lIGMoIk5vdCBSZXBvcnRlZCIsICJVbmF2YWlsYWJsZSIpLF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlcm1zID0gImV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24rbGdnX2dyb3VwK2NsdXN0ZXIrYWdlX2F0X2RpYWdub3Npc195ZWFycytTQkkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X0VGU19hZGRpdGl2ZV90ZXJtc19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfU0JJLlJEUyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm11bHRpdmFyaWF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyc19jb2wgPSAiRUZTX3llYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c19jb2wgPSAiRUZTX3N0YXR1cyIpCgpmb3Jlc3RfZWZzIDwtIHBsb3RGb3Jlc3QocmVhZFJEUyhmaWxlLnBhdGgocmVzdWx0c19kaXIsICJjb3hfRUZTX2FkZGl0aXZlX3Rlcm1zX3Jlc2VjdGlvbl9sZ2dfZ3JvdXBfY2x1c3Rlcl9TQkkuUkRTIikpKQoKZm9yZXN0X2VmcwoKZ2dzYXZlKGZpbGUucGF0aChwbG90X2RpciwgImZvcmVzdF9hZGRfRUZTX3Jlc2VjdGlvbl9sZ2dfZ3JvdXBfY2x1c3Rlcl9hc3NpZ25tZW50X1NCSS5wZGYiKSwKICAgICAgIGZvcmVzdF9lZnMsCiAgICAgICB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2LCB1bml0cyA9ICJpbiIsCiAgICAgICBkZXZpY2UgPSAicGRmIikKYGBgCnJlcGVhdCBhbmFseXNpcywgcmVwbGFjaW5nIFNCSSB3aXRoIEtFR0cgc3BsaWNlb3NvbWUgZ3N2YSBzY29yZQoKYGBge3J9CmFkZF9tb2RlbF9vcyA8LSBmaXRfc2F2ZV9tb2RlbChtZXRhZGF0YVshbWV0YWRhdGEkZXh0ZW50X29mX3R1bW9yX3Jlc2VjdGlvbiAlaW4lIGMoIk5vdCBSZXBvcnRlZCIsICJVbmF2YWlsYWJsZSIpLF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlcm1zID0gImV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24rbGdnX2dyb3VwK2NsdXN0ZXIrYWdlX2F0X2RpYWdub3Npc195ZWFycytzcGxpY2Vvc29tZV9nc3ZhX3Njb3JlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUucGF0aChyZXN1bHRzX2RpciwgImNveF9PU19hZGRpdGl2ZV90ZXJtc19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfc3BsaWNlb3NvbWVfc2NvcmUuUkRTIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibXVsdGl2YXJpYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXJzX2NvbCA9ICJPU195ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNfY29sID0gIk9TX3N0YXR1cyIpCgpmb3Jlc3Rfb3MgPC0gcGxvdEZvcmVzdChyZWFkUkRTKGZpbGUucGF0aChyZXN1bHRzX2RpciwgImNveF9PU19hZGRpdGl2ZV90ZXJtc19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfc3BsaWNlb3NvbWVfc2NvcmUuUkRTIikpKQoKZm9yZXN0X29zCgpnZ3NhdmUoZmlsZS5wYXRoKHBsb3RfZGlyLCAiZm9yZXN0X2FkZF9PU19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfYXNzaWdubWVudF9zcGxpY2Vvc29tZV9zY29yZS5wZGYiKSwKICAgICAgIGZvcmVzdF9vcywKICAgICAgIHdpZHRoID0gMTAsIGhlaWdodCA9IDYsIHVuaXRzID0gImluIiwKICAgICAgIGRldmljZSA9ICJwZGYiKQpgYGAKCgpgYGB7ciBJbnRlcmFjdGlvbiBtb2RlbHMgd2l0aCBHU1ZBIGFuZCBTQkl9Cm1vZGVscyA8LSBjKCJzcGxpY2Vvc29tZV9nc3ZhX3Njb3JlIiwgIlNCSSIpCgpmb3IgKGVhY2ggaW4gbW9kZWxzKSB7CiAgaW50X21vZGVsX2VmcyA8LSBmaXRfc2F2ZV9tb2RlbChtZXRhZGF0YVshbWV0YWRhdGEkZXh0ZW50X29mX3R1bW9yX3Jlc2VjdGlvbiAlaW4lIGMoIk5vdCBSZXBvcnRlZCIsICJVbmF2YWlsYWJsZSIpLF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVybXMgPSBwYXN0ZTAoImV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24rbGdnX2dyb3VwK2NsdXN0ZXIqIiwgZWFjaCwgIithZ2VfYXRfZGlhZ25vc2lzX3llYXJzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUucGF0aChyZXN1bHRzX2RpciwgcGFzdGUwKCJjb3hfRUZTX2ludGVyYWN0aW9uX3Rlcm1zX3Jlc2VjdGlvbl9sZ2dfZ3JvdXBfY2x1c3Rlcl8iLCBlYWNoLCAiLlJEUyIpKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm11bHRpdmFyaWF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXJzX2NvbCA9ICJFRlNfeWVhcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNfY29sID0gIkVGU19zdGF0dXMiKQogIAogIGludF9mb3Jlc3RfZWZzIDwtIHBsb3RGb3Jlc3QocmVhZFJEUyhmaWxlLnBhdGgocmVzdWx0c19kaXIsIHBhc3RlMCgiY294X0VGU19pbnRlcmFjdGlvbl90ZXJtc19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfIiwgZWFjaCwgIi5SRFMiKSkpKQogIAogIGludF9mb3Jlc3RfZWZzCiAgCiAgZ2dzYXZlKGZpbGUucGF0aChwbG90X2RpciwgcGFzdGUwKCJmb3Jlc3RfaW50X0VGU19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfYXNzaWdubWVudF8iLCBlYWNoLCAiLnBkZiIpKSwKICAgICAgICAgaW50X2ZvcmVzdF9lZnMsCiAgICAgICAgIHdpZHRoID0gMTAsIGhlaWdodCA9IDYsIHVuaXRzID0gImluIiwKICAgICAgICAgZGV2aWNlID0gInBkZiIpCgogIGludF9tb2RlbF9vcyA8LSBmaXRfc2F2ZV9tb2RlbChtZXRhZGF0YVshbWV0YWRhdGEkZXh0ZW50X29mX3R1bW9yX3Jlc2VjdGlvbiAlaW4lIGMoIk5vdCBSZXBvcnRlZCIsICJVbmF2YWlsYWJsZSIpLF0sCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVybXMgPSBwYXN0ZTAoImV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24rbGdnX2dyb3VwK2NsdXN0ZXIqIiwgZWFjaCwgIithZ2VfYXRfZGlhZ25vc2lzX3llYXJzIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUucGF0aChyZXN1bHRzX2RpciwgcGFzdGUwKCJjb3hfT1NfaW50ZXJhY3Rpb25fdGVybXNfcmVzZWN0aW9uX2xnZ19ncm91cF9jbHVzdGVyXyIsIGVhY2gsICIuUkRTIikpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibXVsdGl2YXJpYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVhcnNfY29sID0gIk9TX3llYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzX2NvbCA9ICJPU19zdGF0dXMiKQogIAogIGludF9mb3Jlc3Rfb3MgPC0gcGxvdEZvcmVzdChyZWFkUkRTKGZpbGUucGF0aChyZXN1bHRzX2RpciwgcGFzdGUwKCJjb3hfT1NfaW50ZXJhY3Rpb25fdGVybXNfcmVzZWN0aW9uX2xnZ19ncm91cF9jbHVzdGVyXyIsIGVhY2gsICIuUkRTIikpKSkKICAKICBpbnRfZm9yZXN0X29zCiAgCiAgZ2dzYXZlKGZpbGUucGF0aChwbG90X2RpciwgcGFzdGUwKCJmb3Jlc3RfaW50X09TX3Jlc2VjdGlvbl9sZ2dfZ3JvdXBfY2x1c3Rlcl9hc3NpZ25tZW50XyIsIGVhY2gsICIucGRmIikpLAogICAgICAgICBpbnRfZm9yZXN0X29zLAogICAgICAgICB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2LCB1bml0cyA9ICJpbiIsCiAgICAgICAgIGRldmljZSA9ICJwZGYiKQogIAp9CgphZGRfbW9kZWxfZWZzIDwtIGZpdF9zYXZlX21vZGVsKG1ldGFkYXRhWyFtZXRhZGF0YSRleHRlbnRfb2ZfdHVtb3JfcmVzZWN0aW9uICVpbiUgYygiTm90IFJlcG9ydGVkIiwgIlVuYXZhaWxhYmxlIiksXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVybXMgPSAiZXh0ZW50X29mX3R1bW9yX3Jlc2VjdGlvbitsZ2dfZ3JvdXArY2x1c3RlcithZ2VfYXRfZGlhZ25vc2lzX3llYXJzK3NwbGljZW9zb21lX2dzdmFfc2NvcmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X0VGU19hZGRpdGl2ZV90ZXJtc19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfc3BsaWNlb3NvbWVfc2NvcmUuUkRTIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibXVsdGl2YXJpYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXJzX2NvbCA9ICJFRlNfeWVhcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzX2NvbCA9ICJFRlNfc3RhdHVzIikKCmZvcmVzdF9lZnMgPC0gcGxvdEZvcmVzdChyZWFkUkRTKGZpbGUucGF0aChyZXN1bHRzX2RpciwgImNveF9FRlNfYWRkaXRpdmVfdGVybXNfcmVzZWN0aW9uX2xnZ19ncm91cF9jbHVzdGVyX3NwbGljZW9zb21lX3Njb3JlLlJEUyIpKSkKCmZvcmVzdF9lZnMKCmdnc2F2ZShmaWxlLnBhdGgocGxvdF9kaXIsICJmb3Jlc3RfYWRkX0VGU19yZXNlY3Rpb25fbGdnX2dyb3VwX2NsdXN0ZXJfYXNzaWdubWVudF9zcGxpY2Vvc29tZV9zY29yZS5wZGYiKSwKICAgICAgIGZvcmVzdF9lZnMsCiAgICAgICB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2LCB1bml0cyA9ICJpbiIsCiAgICAgICBkZXZpY2UgPSAicGRmIikKYGBgCgpTdWJzZXQgYG1ldGFkYXRhYCBmb3IgTEdHLCBhbmQgb25seSBpbmNsdWRlIGNsdXN0ZXJzIHdpdGggPj0gMTAgc2FtcGxlcwoKYGBge3J9CmxnZyA8LSBtZXRhZGF0YSAlPiUKICBkcGx5cjo6ZmlsdGVyKHBsb3RfZ3JvdXAgPT0gIkxvdy1ncmFkZSBnbGlvbWEiKSAlPiUKICBkcGx5cjo6bXV0YXRlKGNsdXN0ZXIgPSBmYWN0b3IoY2x1c3RlcikpICU+JQogIGRwbHlyOjptdXRhdGUobW9sX3N1Yl9ncm91cCA9IGZjdF9yZWxldmVsKG1vbF9zdWJfZ3JvdXAsICJXaWxkdHlwZSIsIGFmdGVyID0gMCkpCgpyZXRhaW5fY2x1c3RlcnNfbGdnIDwtIGxnZyAlPiUKICBkcGx5cjo6Y291bnQoY2x1c3RlcikgJT4lCiAgZmlsdGVyKG4gPj0gMTApICU+JQogIHB1bGwoY2x1c3RlcikKCmxnZyA8LSBsZ2cgJT4lCiAgZmlsdGVyKGNsdXN0ZXIgJWluJSByZXRhaW5fY2x1c3RlcnNfbGdnKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoY2x1c3RlciA9IGZhY3RvcihjbHVzdGVyKSkKYGBgCgpHZW5lcmF0ZSBjb3hwaCBtb2RlbHMgaW5jbHVkaW5nIGNvdmFyaWF0ZXMgYGV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb25gLCBgbW9sX3N1Yl9ncm91cGAsIGBjbHVzdGVyYCwgYW5kIGBTQklgIGFuZCBwbG90CgpgYGB7cn0KIyBpZGVudGlmeSBMR0cgY2x1c3RlcnMKbGdnX2NsdXN0ZXJzIDwtIG1ldGFkYXRhICU+JQogIGZpbHRlcihsZ2dfZ3JvdXAgPT0gIkxHRyIpICU+JQogIG11dGF0ZShjbHVzdGVyID0gYXMuaW50ZWdlcihnc3ViKCJjbHVzdGVyIiwgIiIsIGNsdXN0ZXIpKSkgJT4lCiAgcHVsbChjbHVzdGVyKSAlPiUKICBzb3J0KCkgJT4lCiAgdW5pcXVlKCkKCgphZGRfbW9kZWxfbGdnX2VmcyA8LSBmaXRfc2F2ZV9tb2RlbChsZ2dbIWxnZyRjbHVzdGVyICVpbiUgbGdnX2NsdXN0ZXJzICYgIWxnZyRleHRlbnRfb2ZfdHVtb3JfcmVzZWN0aW9uICVpbiUgYygiTm90IFJlcG9ydGVkIiwgIlVuYXZhaWxhYmxlIiksXSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVybXMgPSAiZXh0ZW50X29mX3R1bW9yX3Jlc2VjdGlvbittb2xfc3ViX2dyb3VwK2NsdXN0ZXIrYWdlX2F0X2RpYWdub3Npc195ZWFycytTQkkiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X2xnZ19FRlNfYWRkaXRpdmVfdGVybXNfcmVzZWN0aW9uX3N1YnR5cGVfY2x1c3Rlcl9TQkkuUkRTIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibXVsdGl2YXJpYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXJzX2NvbCA9ICJFRlNfeWVhcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzX2NvbCA9ICJFRlNfc3RhdHVzIikKCmZvcmVzdF9sZ2dfZWZzIDwtIHBsb3RGb3Jlc3QocmVhZFJEUyhmaWxlLnBhdGgocmVzdWx0c19kaXIsICJjb3hfbGdnX0VGU19hZGRpdGl2ZV90ZXJtc19yZXNlY3Rpb25fc3VidHlwZV9jbHVzdGVyX1NCSS5SRFMiKSkpCgpmb3Jlc3RfbGdnX2VmcwoKZ2dzYXZlKGZpbGUucGF0aChwbG90X2RpciwgImZvcmVzdF9hZGRfRUZTX0xHR19yZXNlY3Rpb25fc3VidHlwZV9jbHVzdGVyX2Fzc2lnbm1lbnRfU0JJLnBkZiIpLAogICAgICAgZm9yZXN0X2xnZ19lZnMsCiAgICAgICB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2LCB1bml0cyA9ICJpbiIsCiAgICAgICBkZXZpY2UgPSAicGRmIikKYGBgCgoKcmVwZWF0IGFuYWx5c2lzIHJlcGxhY2luZyBgU0JJYCB3aXRoIGBzcGxpY2Vvc29tZV9nc3ZhX3Njb3JlYAoKYGBge3J9CmFkZF9tb2RlbF9sZ2dfZWZzIDwtIGZpdF9zYXZlX21vZGVsKGxnZ1shbGdnJGNsdXN0ZXIgJWluJSBsZ2dfY2x1c3RlcnMgJiAhbGdnJGV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24gJWluJSBjKCJOb3QgUmVwb3J0ZWQiLCAiVW5hdmFpbGFibGUiKSxdLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXJtcyA9ICJleHRlbnRfb2ZfdHVtb3JfcmVzZWN0aW9uK21vbF9zdWJfZ3JvdXArY2x1c3RlcithZ2VfYXRfZGlhZ25vc2lzX3llYXJzK3NwbGljZW9zb21lX2dzdmFfc2NvcmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X2xnZ19FRlNfYWRkaXRpdmVfdGVybXNfcmVzZWN0aW9uX3N1YnR5cGVfY2x1c3Rlcl9zcGxpY2Vvc29tZV9zY29yZS5SRFMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtdWx0aXZhcmlhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVhcnNfY29sID0gIkVGU195ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNfY29sID0gIkVGU19zdGF0dXMiKQoKZm9yZXN0X2xnZ19lZnMgPC0gcGxvdEZvcmVzdChyZWFkUkRTKGZpbGUucGF0aChyZXN1bHRzX2RpciwgImNveF9sZ2dfRUZTX2FkZGl0aXZlX3Rlcm1zX3Jlc2VjdGlvbl9zdWJ0eXBlX2NsdXN0ZXJfc3BsaWNlb3NvbWVfc2NvcmUuUkRTIikpKQoKZm9yZXN0X2xnZ19lZnMKCmdnc2F2ZShmaWxlLnBhdGgocGxvdF9kaXIsICJmb3Jlc3RfYWRkX0VGU19MR0dfcmVzZWN0aW9uX3N1YnR5cGVfY2x1c3Rlcl9hc3NpZ25tZW50X3NwbGljZW9zb21lX3Njb3JlLnBkZiIpLAogICAgICAgZm9yZXN0X2xnZ19lZnMsCiAgICAgICB3aWR0aCA9IDEwLCBoZWlnaHQgPSA2LCB1bml0cyA9ICJpbiIsCiAgICAgICBkZXZpY2UgPSAicGRmIikKYGBgCgpTdWJzZXQgYG1ldGFkYXRhYCBmb3IgSEdHIGFuZCByZXRhaW4gY2x1c3RlciB3aXRoIG4gPj0gMTAKCmBgYHtyfQpoZ2cgPC0gbWV0YWRhdGEgJT4lCiAgZHBseXI6OmZpbHRlcihwbG90X2dyb3VwICVpbiUgYygiT3RoZXIgaGlnaC1ncmFkZSBnbGlvbWEiLCAiRGlmZnVzZSBtaWRsaW5lIGdsaW9tYSIpKSAlPiUKICBkcGx5cjo6bXV0YXRlKGNsdXN0ZXIgPSBmYWN0b3IoY2x1c3RlcikpICU+JQogIGRwbHlyOjptdXRhdGUobW9sX3N1Yl9ncm91cCA9IGZjdF9yZWxldmVsKG1vbF9zdWJfZ3JvdXAsICJIR0csIEgzIHdpbGR0eXBlIiwgYWZ0ZXIgPSAwKSkgJT4lCiAgZHBseXI6OmZpbHRlcighaXMubmEoT1NfZGF5cykgfCAhaXMubmEoRUZTX2RheXMpKQoKcmV0YWluX2NsdXN0ZXJzX2hnZyA8LSBoZ2cgJT4lCiAgZHBseXI6OmNvdW50KGNsdXN0ZXIpICU+JQogIGZpbHRlcihuID49IDEwKSAlPiUKICBwdWxsKGNsdXN0ZXIpCgpoZ2cgPC0gaGdnICU+JQogIGZpbHRlcihjbHVzdGVyICVpbiUgcmV0YWluX2NsdXN0ZXJzX2hnZykgJT4lCiAgZHBseXI6Om11dGF0ZShjbHVzdGVyID0gZmFjdG9yKGNsdXN0ZXIpKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoU0lfZ3JvdXAgPSBjYXNlX3doZW4oCiAgICAgIFNCSSA+IHN1bW1hcnkoU0JJKVsiM3JkIFF1LiJdIH4gIkhpZ2ggU0JJIiwKICAgICAgU0JJIDwgc3VtbWFyeShTQkkpWyIxc3QgUXUuIl0gfiAiTG93IFNCSSIsCiAgICAgIFRSVUUgfiBOQV9jaGFyYWN0ZXJfCiAgICApKSAlPiUKICBkcGx5cjo6bXV0YXRlKHNwbGljZW9zb21lX2dyb3VwID0gY2FzZV93aGVuKAogICAgICBzcGxpY2Vvc29tZV9nc3ZhX3Njb3JlID4gc3VtbWFyeShzcGxpY2Vvc29tZV9nc3ZhX3Njb3JlKVsiM3JkIFF1LiJdIH4gIlNwbGljZSBHU1ZBIDR0aCBRIiwKICAgICAgc3BsaWNlb3NvbWVfZ3N2YV9zY29yZSA+IHN1bW1hcnkoc3BsaWNlb3NvbWVfZ3N2YV9zY29yZSlbIk1lZGlhbiJdIH4gIlNwbGljZSBHU1ZBIDNyZCBRIiwKICAgICAgc3BsaWNlb3NvbWVfZ3N2YV9zY29yZSA+IHN1bW1hcnkoc3BsaWNlb3NvbWVfZ3N2YV9zY29yZSlbIjFzdCBRdS4iXSB+ICJTcGxpY2UgR1NWQSAybmQgUSIsCiAgICAgIFRSVUUgfiAiU3BsaWNlIEdTVkEgMXN0IFEiCiAgICApKSAlPiUKICBkcGx5cjo6bXV0YXRlKFNJX2dyb3VwID0gZmN0X3JlbGV2ZWwoU0lfZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCJIaWdoIFNCSSIsICJMb3cgU0JJIikpKSAlPiUKICBkcGx5cjo6bXV0YXRlKHNwbGljZW9zb21lX2dyb3VwID0gZmN0X3JlbGV2ZWwoc3BsaWNlb3NvbWVfZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCJTcGxpY2UgR1NWQSAxc3QgUSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3BsaWNlIEdTVkEgMm5kIFEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNwbGljZSBHU1ZBIDNyZCBRIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNwbGljZSBHU1ZBIDR0aCBRIikpKQpgYGAKCgpHZW5lcmF0ZSBIR0cgS00gbW9kZWxzIHdpdGggYHNwbGljZW9zb21lX2dyb3VwYCBhcyBjb3ZhcmlhdGUKCmBgYHtyfQojIEdlbmVyYXRlIGthcGxhbiBtZWllciBzdXJ2aXZhbCBtb2RlbHMgZm9yIE9TIGFuZCBFRlMsIGFuZCBzYXZlIG91dHB1dHMKaGdnX2thcF9vcyA8LSBzdXJ2aXZhbF9hbmFseXNpcygKICBtZXRhZGF0YSAgPSBoZ2cgJT4lIGRwbHlyOjpmaWx0ZXIoIWlzLm5hKHNwbGljZW9zb21lX2dyb3VwKSksCiAgaW5kX3ZhciA9ICJzcGxpY2Vvc29tZV9ncm91cCIsCiAgdGVzdCA9ICJrYXAubWVpZXIiLAogIG1ldGFkYXRhX3NhbXBsZV9jb2wgPSAiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIsCiAgZGF5c19jb2wgPSAiT1NfZGF5cyIsCiAgc3RhdHVzX2NvbCA9ICJPU19zdGF0dXMiCikKCnJlYWRyOjp3cml0ZV9yZHMoaGdnX2thcF9vcywKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgocmVzdWx0c19kaXIsICJsb2dyYW5rX2hnZ19PU19zcGxpY2VfZ3JvdXAuUkRTIikpCgpoZ2dfa2FwX2VmcyA8LSBzdXJ2aXZhbF9hbmFseXNpcygKICBtZXRhZGF0YSAgPSBoZ2cgJT4lIGRwbHlyOjpmaWx0ZXIoIWlzLm5hKHNwbGljZW9zb21lX2dyb3VwKSksCiAgaW5kX3ZhciA9ICJzcGxpY2Vvc29tZV9ncm91cCIsCiAgdGVzdCA9ICJrYXAubWVpZXIiLAogIG1ldGFkYXRhX3NhbXBsZV9jb2wgPSAiS2lkc19GaXJzdF9CaW9zcGVjaW1lbl9JRCIsCiAgZGF5c19jb2wgPSAiRUZTX2RheXMiLAogIHN0YXR1c19jb2wgPSAiRUZTX3N0YXR1cyIKKQoKcmVhZHI6OndyaXRlX3JkcyhoZ2dfa2FwX2VmcywKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgocmVzdWx0c19kaXIsICJsb2dyYW5rX2hnZ19FRlNfc3BsaWNlX2dyb3VwLlJEUyIpKQpgYGAKCkdlbmVyYXRlIEtNIHBsb3RzCgpgYGB7cn0Ka21faGdnX29zX3Bsb3QgPC0gcGxvdEtNKG1vZGVsID0gaGdnX2thcF9vcywKICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZSA9ICJzcGxpY2Vvc29tZV9ncm91cCIsCiAgICAgICAgICAgICAgICAgICAgY29tYmluZWQgPSBGLCAKICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJIR0csIG92ZXJhbGwgc3Vydml2YWwiLAogICAgICAgICAgICAgICAgICAgIHBfcG9zID0gInRvcHJpZ2h0IikKCmdnc2F2ZShmaWxlLnBhdGgocGxvdF9kaXIsICJrbV9oZ2dfT1Nfc3BsaWNlb3NvbWVfc2NvcmUucGRmIiksCiAgICAgICBrbV9oZ2dfb3NfcGxvdCwKICAgICAgIHdpZHRoID0gOSwgaGVpZ2h0ID0gNSwgdW5pdHMgPSAiaW4iLAogICAgICAgZGV2aWNlID0gInBkZiIpCgprbV9oZ2dfZWZzX3Bsb3QgPC0gcGxvdEtNKG1vZGVsID0gaGdnX2thcF9lZnMsCiAgICAgICAgICAgICAgICAgICAgdmFyaWFibGUgPSAic3BsaWNlb3NvbWVfZ3JvdXAiLAogICAgICAgICAgICAgICAgICAgIGNvbWJpbmVkID0gRiwgCiAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiSEdHLCBldmVudC1mcmVlIHN1cnZpdmFsIiwKICAgICAgICAgICAgICAgICAgICBwX3BvcyA9ICJ0b3ByaWdodCIpCgpnZ3NhdmUoZmlsZS5wYXRoKHBsb3RfZGlyLCAia21faGdnX0VGU19zcGxpY2Vvc29tZV9zY29yZS5wZGYiKSwgCiAgICAgICBrbV9oZ2dfZWZzX3Bsb3QsCiAgICAgICB3aWR0aCA9IDksIGhlaWdodCA9IDUsIHVuaXRzID0gImluIiwKICAgICAgIGRldmljZSA9ICJwZGYiKQpgYGAKCkdlbmVyYXRlIGNveHBoIG1vZGVscyBmb3IgSEdHIGluY2x1ZGluZyBjb3ZhcmlhdGVzIGBtb2xfc3ViX2dyb3VwYCBgY2x1c3RlcmAsIGFuZCBgU0JJYCwgYW5kIHBsb3QKCmBgYHtyfQphZGRfbW9kZWxfaGdnX29zIDwtIGZpdF9zYXZlX21vZGVsKGhnZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVybXMgPSAibW9sX3N1Yl9ncm91cCthZ2VfYXRfZGlhZ25vc2lzX3llYXJzK1NCSSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlLnBhdGgocmVzdWx0c19kaXIsICJjb3hfaGdnX09TX2FkZGl0aXZlX3Rlcm1zX3N1YnR5cGVfY2x1c3Rlcl9TQkkuUkRTIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibXVsdGl2YXJpYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXJzX2NvbCA9ICJPU195ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNfY29sID0gIk9TX3N0YXR1cyIpCgpmb3Jlc3RfaGdnX29zIDwtIHBsb3RGb3Jlc3QocmVhZFJEUyhmaWxlLnBhdGgocmVzdWx0c19kaXIsICJjb3hfaGdnX09TX2FkZGl0aXZlX3Rlcm1zX3N1YnR5cGVfY2x1c3Rlcl9TQkkuUkRTIikpKQoKZm9yZXN0X2hnZ19vcwoKZ2dzYXZlKGZpbGUucGF0aChwbG90X2RpciwgImZvcmVzdF9hZGRfT1NfSEdHX3N1YnR5cGVfY2x1c3Rlcl9hc3NpZ25tZW50X1NCSS5wZGYiKSwKICAgICAgIGZvcmVzdF9oZ2dfb3MsCiAgICAgICB3aWR0aCA9IDksIGhlaWdodCA9IDUsIHVuaXRzID0gImluIiwKICAgICAgIGRldmljZSA9ICJwZGYiKQoKYWRkX21vZGVsX2hnZ19lZnMgPC0gZml0X3NhdmVfbW9kZWwoaGdnLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0ZXJtcyA9ICJtb2xfc3ViX2dyb3VwK2FnZV9hdF9kaWFnbm9zaXNfeWVhcnMrU0JJIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbGUucGF0aChyZXN1bHRzX2RpciwgImNveF9oZ2dfRUZTX2FkZGl0aXZlX3Rlcm1zX3N1YnR5cGVfY2x1c3Rlcl9TQkkuUkRTIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibXVsdGl2YXJpYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXJzX2NvbCA9ICJFRlNfeWVhcnMiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhdHVzX2NvbCA9ICJFRlNfc3RhdHVzIikKCmZvcmVzdF9oZ2dfZWZzIDwtIHBsb3RGb3Jlc3QocmVhZFJEUyhmaWxlLnBhdGgocmVzdWx0c19kaXIsICJjb3hfaGdnX0VGU19hZGRpdGl2ZV90ZXJtc19zdWJ0eXBlX2NsdXN0ZXJfU0JJLlJEUyIpKSkKCmdnc2F2ZShmaWxlLnBhdGgocGxvdF9kaXIsICJmb3Jlc3RfYWRkX0VGU19IR0dfc3VidHlwZV9jbHVzdGVyX2Fzc2lnbm1lbnRfU0JJLnBkZiIpLAogICAgICAgZm9yZXN0X2hnZ19lZnMsCiAgICAgICB3aWR0aCA9IDksIGhlaWdodCA9IDUsIHVuaXRzID0gImluIiwKICAgICAgIGRldmljZSA9ICJwZGYiKQpgYGAKClJlcGVhdCBhbmFseXNpcyByZXBsYWNpbmcgYFNCSWAgd2l0aCBgc3BsaWNlb3NvbWVfZ3N2YV9zY29yZWAKCmBgYHtyfQphZGRfbW9kZWxfaGdnX29zIDwtIGZpdF9zYXZlX21vZGVsKGhnZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVybXMgPSAibW9sX3N1Yl9ncm91cCthZ2VfYXRfZGlhZ25vc2lzX3llYXJzK3NwbGljZW9zb21lX2dzdmFfc2NvcmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X2hnZ19PU19hZGRpdGl2ZV90ZXJtc19zdWJ0eXBlX2NsdXN0ZXJfc3BsaWNlb3NvbWVfc2NvcmUuUkRTIiksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAibXVsdGl2YXJpYXRlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHllYXJzX2NvbCA9ICJPU195ZWFycyIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGF0dXNfY29sID0gIk9TX3N0YXR1cyIpCgpmb3Jlc3RfaGdnX29zIDwtIHBsb3RGb3Jlc3QocmVhZFJEUyhmaWxlLnBhdGgocmVzdWx0c19kaXIsICJjb3hfaGdnX09TX2FkZGl0aXZlX3Rlcm1zX3N1YnR5cGVfY2x1c3Rlcl9zcGxpY2Vvc29tZV9zY29yZS5SRFMiKSkpCgpmb3Jlc3RfaGdnX29zCgpnZ3NhdmUoZmlsZS5wYXRoKHBsb3RfZGlyLCAiZm9yZXN0X2FkZF9PU19IR0dfc3VidHlwZV9jbHVzdGVyX2Fzc2lnbm1lbnRfc3BsaWNlb3NvbWVfc2NvcmUucGRmIiksCiAgICAgICBmb3Jlc3RfaGdnX29zLAogICAgICAgd2lkdGggPSA5LCBoZWlnaHQgPSA1LCB1bml0cyA9ICJpbiIsCiAgICAgICBkZXZpY2UgPSAicGRmIikKCmFkZF9tb2RlbF9oZ2dfZWZzIDwtIGZpdF9zYXZlX21vZGVsKGhnZywKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVybXMgPSAibW9sX3N1Yl9ncm91cCthZ2VfYXRfZGlhZ25vc2lzX3llYXJzK3NwbGljZW9zb21lX2dzdmFfc2NvcmUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X2hnZ19FRlNfYWRkaXRpdmVfdGVybXNfc3VidHlwZV9jbHVzdGVyX3NwbGljZW9zb21lX3Njb3JlLlJEUyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm11bHRpdmFyaWF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyc19jb2wgPSAiRUZTX3llYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c19jb2wgPSAiRUZTX3N0YXR1cyIpCgpmb3Jlc3RfaGdnX2VmcyA8LSBwbG90Rm9yZXN0KHJlYWRSRFMoZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X2hnZ19FRlNfYWRkaXRpdmVfdGVybXNfc3VidHlwZV9jbHVzdGVyX3NwbGljZW9zb21lX3Njb3JlLlJEUyIpKSkKCmdnc2F2ZShmaWxlLnBhdGgocGxvdF9kaXIsICJmb3Jlc3RfYWRkX0VGU19IR0dfc3VidHlwZV9jbHVzdGVyX2Fzc2lnbm1lbnRfc3BsaWNlb3NvbWVfc2NvcmUucGRmIiksCiAgICAgICBmb3Jlc3RfaGdnX2VmcywKICAgICAgIHdpZHRoID0gOSwgaGVpZ2h0ID0gNSwgdW5pdHMgPSAiaW4iLAogICAgICAgZGV2aWNlID0gInBkZiIpCmBgYApGaWx0ZXIgZm9yIGNsdXN0ZXIgNwoKYGBge3J9CmNsdXN0ZXI3X2RmIDwtIG1ldGFkYXRhICU+JQogIGRwbHlyOjpmaWx0ZXIoY2x1c3RlciA9PSAiQ2x1c3RlciA3IiwKICAgICAgICAgICAgICAgICFpcy5uYShFRlNfZGF5cykpICU+JQogIGRwbHlyOjptdXRhdGUoU0lfZ3JvdXAgPSBjYXNlX3doZW4oCiAgICAgIFNCSSA+IHN1bW1hcnkoU0JJKVsiM3JkIFF1LiJdIH4gIkhpZ2ggU0JJIiwKICAgICAgU0JJIDwgc3VtbWFyeShTQkkpWyIxc3QgUXUuIl0gfiAiTG93IFNCSSIsCiAgICAgIFRSVUUgfiBOQV9jaGFyYWN0ZXJfCiAgICApKSAlPiUKICBkcGx5cjo6bXV0YXRlKHNwbGljZW9zb21lX2dyb3VwID0gY2FzZV93aGVuKAogICAgICBzcGxpY2Vvc29tZV9nc3ZhX3Njb3JlID4gc3VtbWFyeShzcGxpY2Vvc29tZV9nc3ZhX3Njb3JlKVsiM3JkIFF1LiJdIH4gIlNwbGljZSBHU1ZBIDR0aCBRIiwKICAgICAgc3BsaWNlb3NvbWVfZ3N2YV9zY29yZSA+IHN1bW1hcnkoc3BsaWNlb3NvbWVfZ3N2YV9zY29yZSlbIk1lZGlhbiJdIH4gIlNwbGljZSBHU1ZBIDNyZCBRIiwKICAgICAgc3BsaWNlb3NvbWVfZ3N2YV9zY29yZSA+IHN1bW1hcnkoc3BsaWNlb3NvbWVfZ3N2YV9zY29yZSlbIjFzdCBRdS4iXSB+ICJTcGxpY2UgR1NWQSAybmQgUSIsCiAgICAgIFRSVUUgfiAiU3BsaWNlIEdTVkEgMXN0IFEiCiAgICApKSAlPiUKICBkcGx5cjo6bXV0YXRlKFNJX2dyb3VwID0gZmN0X3JlbGV2ZWwoU0lfZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCJIaWdoIFNCSSIsICJMb3cgU0JJIikpKSAlPiUKICBkcGx5cjo6bXV0YXRlKHNwbGljZW9zb21lX2dyb3VwID0gZmN0X3JlbGV2ZWwoc3BsaWNlb3NvbWVfZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjKCJTcGxpY2UgR1NWQSAxc3QgUSIsIAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAiU3BsaWNlIEdTVkEgMm5kIFEiLCAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNwbGljZSBHU1ZBIDNyZCBRIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIlNwbGljZSBHU1ZBIDR0aCBRIikpKQpgYGAKCkdlbmVyYXRlIEtNIG1vZGVscyB3aXRoIGBTSV9ncm91cGAgYXMgY292YXJpYXRlCgpgYGB7cn0KIyBHZW5lcmF0ZSBrYXBsYW4gbWVpZXIgc3Vydml2YWwgbW9kZWxzIGZvciBPUyBhbmQgRUZTLCBhbmQgc2F2ZSBvdXRwdXRzCmM3X3NpX2thcF9vcyA8LSBzdXJ2aXZhbF9hbmFseXNpcygKICBtZXRhZGF0YSAgPSBjbHVzdGVyN19kZiAlPiUgZHBseXI6OmZpbHRlcighaXMubmEoU0lfZ3JvdXApKSwKICBpbmRfdmFyID0gIlNJX2dyb3VwIiwKICB0ZXN0ID0gImthcC5tZWllciIsCiAgbWV0YWRhdGFfc2FtcGxlX2NvbCA9ICJLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lEIiwKICBkYXlzX2NvbCA9ICJPU19kYXlzIiwKICBzdGF0dXNfY29sID0gIk9TX3N0YXR1cyIKKQoKcmVhZHI6OndyaXRlX3JkcyhjN19zaV9rYXBfb3MsCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAibG9ncmFua19jbHVzdGVyN19PU19TQkkuUkRTIikpCgpjN19zaV9rYXBfZWZzIDwtIHN1cnZpdmFsX2FuYWx5c2lzKAogIG1ldGFkYXRhICA9IGNsdXN0ZXI3X2RmICU+JSBkcGx5cjo6ZmlsdGVyKCFpcy5uYShTSV9ncm91cCkpLAogIGluZF92YXIgPSAiU0lfZ3JvdXAiLAogIHRlc3QgPSAia2FwLm1laWVyIiwKICBtZXRhZGF0YV9zYW1wbGVfY29sID0gIktpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQiLAogIGRheXNfY29sID0gIkVGU19kYXlzIiwKICBzdGF0dXNfY29sID0gIkVGU19zdGF0dXMiCikKCnJlYWRyOjp3cml0ZV9yZHMoYzdfc2lfa2FwX2VmcywKICAgICAgICAgICAgICAgICBmaWxlLnBhdGgocmVzdWx0c19kaXIsICJsb2dyYW5rX2NsdXN0ZXI3X0VGU19TQkkuUkRTIikpCmBgYAoKR2VuZXJhdGUgQ2x1c3RlciA3IEtNIFNJX2dyb3VwIHBsb3RzCgpgYGB7cn0Ka21fYzdfc2lfb3NfcGxvdCA8LSBwbG90S00obW9kZWwgPSBjN19zaV9rYXBfb3MsCiAgICAgICAgICAgICAgICAgICAgdmFyaWFibGUgPSAiU0lfZ3JvdXAiLAogICAgICAgICAgICAgICAgICAgIGNvbWJpbmVkID0gRiwgCiAgICAgICAgICAgICAgICAgICAgdGl0bGUgPSAiQ2x1c3RlciA3LCBvdmVyYWxsIHN1cnZpdmFsIiwKICAgICAgICAgICAgICAgICAgICBwX3BvcyA9ICJ0b3ByaWdodCIpCgpnZ3NhdmUoZmlsZS5wYXRoKHBsb3RfZGlyLCAia21fY2x1c3RlcjdfT1Nfc2JpX2dyb3VwLnBkZiIpLAogICAgICAga21fYzdfc2lfb3NfcGxvdCwKICAgICAgIHdpZHRoID0gOCwgaGVpZ2h0ID0gNSwgdW5pdHMgPSAiaW4iLAogICAgICAgZGV2aWNlID0gInBkZiIpCgprbV9jN19zaV9lZnNfcGxvdCA8LSBwbG90S00obW9kZWwgPSBjN19zaV9rYXBfZWZzLAogICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlID0gIlNJX2dyb3VwIiwKICAgICAgICAgICAgICAgICAgICBjb21iaW5lZCA9IEYsIAogICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIkNsdXN0ZXIgNywgZXZlbnQtZnJlZSBzdXJ2aXZhbCIsCiAgICAgICAgICAgICAgICAgICAgcF9wb3MgPSAidG9wcmlnaHQiKQoKZ2dzYXZlKGZpbGUucGF0aChwbG90X2RpciwgImttX2NsdXN0ZXI3X0VGU19zYmlfZ3JvdXAucGRmIiksIAogICAgICAga21fYzdfc2lfZWZzX3Bsb3QsCiAgICAgICB3aWR0aCA9IDgsIGhlaWdodCA9IDUsIHVuaXRzID0gImluIiwKICAgICAgIGRldmljZSA9ICJwZGYiKQpgYGAKCgpHZW5lcmF0ZSBLTSBtb2RlbHMgd2l0aCBgc3BsaWNlb3NvbWVfZ3JvdXBgIGFzIGNvdmFyaWF0ZQoKYGBge3J9CiMgR2VuZXJhdGUga2FwbGFuIG1laWVyIHN1cnZpdmFsIG1vZGVscyBmb3IgT1MgYW5kIEVGUywgYW5kIHNhdmUgb3V0cHV0cwpjN19zcGxpY2Vfa2FwX29zIDwtIHN1cnZpdmFsX2FuYWx5c2lzKAogIG1ldGFkYXRhICA9IGNsdXN0ZXI3X2RmICU+JSAKICAgIGRwbHlyOjpmaWx0ZXIoc3BsaWNlb3NvbWVfZ3JvdXAgJWluJSBjKCJTcGxpY2UgR1NWQSA0dGggUSIsICJTcGxpY2UgR1NWQSAxc3QgUSIpKSAlPiUKICAgIGRwbHlyOjptdXRhdGUoc3BsaWNlb3NvbWVfZ3JvdXAgPSBmYWN0b3Ioc3BsaWNlb3NvbWVfZ3JvdXAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gYygiU3BsaWNlIEdTVkEgMXN0IFEiLCAiU3BsaWNlIEdTVkEgNHRoIFEiKSkpLAogIGluZF92YXIgPSAic3BsaWNlb3NvbWVfZ3JvdXAiLAogIHRlc3QgPSAia2FwLm1laWVyIiwKICBtZXRhZGF0YV9zYW1wbGVfY29sID0gIktpZHNfRmlyc3RfQmlvc3BlY2ltZW5fSUQiLAogIGRheXNfY29sID0gIk9TX2RheXMiLAogIHN0YXR1c19jb2wgPSAiT1Nfc3RhdHVzIgopCgpyZWFkcjo6d3JpdGVfcmRzKGM3X3NwbGljZV9rYXBfb3MsCiAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAibG9ncmFua19jbHVzdGVyN19PU19zcGxpY2VfZ3JvdXAuUkRTIikpCgpjN19zcGxpY2Vfa2FwX2VmcyA8LSBzdXJ2aXZhbF9hbmFseXNpcygKICBtZXRhZGF0YSAgPSBjbHVzdGVyN19kZiAlPiUgCiAgICBkcGx5cjo6ZmlsdGVyKHNwbGljZW9zb21lX2dyb3VwICVpbiUgYygiU3BsaWNlIEdTVkEgNHRoIFEiLCAiU3BsaWNlIEdTVkEgMXN0IFEiKSkgJT4lCiAgICBkcGx5cjo6bXV0YXRlKHNwbGljZW9zb21lX2dyb3VwID0gZmFjdG9yKHNwbGljZW9zb21lX2dyb3VwLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IGMoIlNwbGljZSBHU1ZBIDFzdCBRIiwgIlNwbGljZSBHU1ZBIDR0aCBRIikpKSwKICBpbmRfdmFyID0gInNwbGljZW9zb21lX2dyb3VwIiwKICB0ZXN0ID0gImthcC5tZWllciIsCiAgbWV0YWRhdGFfc2FtcGxlX2NvbCA9ICJLaWRzX0ZpcnN0X0Jpb3NwZWNpbWVuX0lEIiwKICBkYXlzX2NvbCA9ICJFRlNfZGF5cyIsCiAgc3RhdHVzX2NvbCA9ICJFRlNfc3RhdHVzIgopCgpyZWFkcjo6d3JpdGVfcmRzKGM3X3NwbGljZV9rYXBfZWZzLAogICAgICAgICAgICAgICAgIGZpbGUucGF0aChyZXN1bHRzX2RpciwgImxvZ3JhbmtfY2x1c3RlcjdfRUZTX3NwbGljZV9ncm91cC5SRFMiKSkKYGBgCgpHZW5lcmF0ZSBDbHVzdGVyIDcgS00gc3BsaWNlb3NvbWVfZ3JvdXAgcGxvdHMKCmBgYHtyfQprbV9jN19zcGxpY2Vfb3NfcGxvdCA8LSBwbG90S00obW9kZWwgPSBjN19zcGxpY2Vfa2FwX29zLAogICAgICAgICAgICAgICAgICAgIHZhcmlhYmxlID0gInNwbGljZW9zb21lX2dyb3VwIiwKICAgICAgICAgICAgICAgICAgICBjb21iaW5lZCA9IEYsIAogICAgICAgICAgICAgICAgICAgIHRpdGxlID0gIkNsdXN0ZXIgNywgb3ZlcmFsbCBzdXJ2aXZhbCIsCiAgICAgICAgICAgICAgICAgICAgcF9wb3MgPSAidG9wcmlnaHQiKQoKZ2dzYXZlKGZpbGUucGF0aChwbG90X2RpciwgImttX2NsdXN0ZXI3X09TX3NwbGljZV9ncm91cC5wZGYiKSwKICAgICAgIGttX2M3X3NwbGljZV9vc19wbG90LAogICAgICAgd2lkdGggPSA5LCBoZWlnaHQgPSA1LCB1bml0cyA9ICJpbiIsCiAgICAgICBkZXZpY2UgPSAicGRmIikKCmttX2M3X3NwbGljZV9lZnNfcGxvdCA8LSBwbG90S00obW9kZWwgPSBjN19zcGxpY2Vfa2FwX2VmcywKICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZSA9ICJzcGxpY2Vvc29tZV9ncm91cCIsCiAgICAgICAgICAgICAgICAgICAgY29tYmluZWQgPSBGLCAKICAgICAgICAgICAgICAgICAgICB0aXRsZSA9ICJDbHVzdGVyIDcsIGV2ZW50LWZyZWUgc3Vydml2YWwiLAogICAgICAgICAgICAgICAgICAgIHBfcG9zID0gInRvcHJpZ2h0IikKCmdnc2F2ZShmaWxlLnBhdGgocGxvdF9kaXIsICJrbV9jbHVzdGVyN19FRlNfc3BsaWNlX2dyb3VwLnBkZiIpLCAKICAgICAgIGttX2M3X3NwbGljZV9lZnNfcGxvdCwKICAgICAgIHdpZHRoID0gOSwgaGVpZ2h0ID0gNSwgdW5pdHMgPSAiaW4iLAogICAgICAgZGV2aWNlID0gInBkZiIpCmBgYApBc3Nlc3MgRUZTIGFuZCBPUyBieSBTQkkgb3Igc3BsaWNlb3NvbWUgR1NWQSBzY29yZSBpbiBtdWx0aXZhcmlhdGUgbW9kZWxzIGFuZCBnZW5lcmF0ZSBmb3Jlc3QgcGxvdHMKCmBgYHtyfQphZGRfbW9kZWxfYzdfZWZzIDwtIGZpdF9zYXZlX21vZGVsKGNsdXN0ZXI3X2RmICU+JSAKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcGx5cjo6ZmlsdGVyKGV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24gIT0gIlVuYXZhaWxhYmxlIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNwbGljZW9zb21lX2dyb3VwICVpbiUgYygiU3BsaWNlIEdTVkEgNHRoIFEiLCAiU3BsaWNlIEdTVkEgMXN0IFEiKSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZHBseXI6Om11dGF0ZShwbG90X2dyb3VwID0gZmN0X3JlbGV2ZWwocGxvdF9ncm91cCwgIkxvdy1ncmFkZSBnbGlvbWEiLCBhZnRlciA9IDApKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGVybXMgPSAiZXh0ZW50X29mX3R1bW9yX3Jlc2VjdGlvbithZ2VfYXRfZGlhZ25vc2lzX3llYXJzK3Bsb3RfZ3JvdXArc3BsaWNlb3NvbWVfZ3JvdXAiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X2hnZ19FRlNfYWRkaXRpdmVfdGVybXNfc3VidHlwZV9jbHVzdGVyX3NwbGljZW9zb21lX3Njb3JlLlJEUyIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIm11bHRpdmFyaWF0ZSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB5ZWFyc19jb2wgPSAiRUZTX3llYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c19jb2wgPSAiRUZTX3N0YXR1cyIpCgpmb3Jlc3RfYzdfc3BsaWNlb3NvbWVfZWZzIDwtIHBsb3RGb3Jlc3QocmVhZFJEUyhmaWxlLnBhdGgocmVzdWx0c19kaXIsICJjb3hfaGdnX0VGU19hZGRpdGl2ZV90ZXJtc19zdWJ0eXBlX2NsdXN0ZXJfc3BsaWNlb3NvbWVfc2NvcmUuUkRTIikpKQoKZ2dzYXZlKGZpbGUucGF0aChwbG90X2RpciwgImZvcmVzdF9hZGRfRUZTX2NsdXN0ZXI3X2hpc3RvbG9neV9yZXNlY3Rpb25fc3BsaWNlb3NvbWVfZ3JvdXAucGRmIiksCiAgICAgICBmb3Jlc3RfYzdfc3BsaWNlb3NvbWVfZWZzLAogICAgICAgd2lkdGggPSA5LCBoZWlnaHQgPSA0LCB1bml0cyA9ICJpbiIsCiAgICAgICBkZXZpY2UgPSAicGRmIikKCmFkZF9tb2RlbF9jN19vcyA8LSBmaXRfc2F2ZV9tb2RlbChjbHVzdGVyN19kZiAlPiUgCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjpmaWx0ZXIoIWV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24gJWluJSBjKCJOb3QgUmVwb3J0ZWQiLCAiVW5hdmFpbGFibGUiKSkgJT4lCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRwbHlyOjptdXRhdGUocGxvdF9ncm91cCA9IGZjdF9yZWxldmVsKHBsb3RfZ3JvdXAsICJMb3ctZ3JhZGUgZ2xpb21hIiwgYWZ0ZXIgPSAwKSksCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRlcm1zID0gImV4dGVudF9vZl90dW1vcl9yZXNlY3Rpb24rYWdlX2F0X2RpYWdub3Npc195ZWFycytwbG90X2dyb3VwK1NCSSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWxlLnBhdGgocmVzdWx0c19kaXIsICJjb3hfaGdnX09TX2FkZGl0aXZlX3Rlcm1zX3N1YnR5cGVfY2x1c3Rlcl9zaV9ncm91cC5SRFMiKSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICJtdWx0aXZhcmlhdGUiLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgeWVhcnNfY29sID0gIk9TX3llYXJzIiwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXR1c19jb2wgPSAiT1Nfc3RhdHVzIikKCmZvcmVzdF9jN19zaV9vcyA8LSBwbG90Rm9yZXN0KHJlYWRSRFMoZmlsZS5wYXRoKHJlc3VsdHNfZGlyLCAiY294X2hnZ19PU19hZGRpdGl2ZV90ZXJtc19zdWJ0eXBlX2NsdXN0ZXJfc2lfZ3JvdXAuUkRTIikpKQoKZ2dzYXZlKGZpbGUucGF0aChwbG90X2RpciwgImZvcmVzdF9hZGRfT1NfY2x1c3RlcjdfaGlzdG9sb2d5X3Jlc2VjdGlvbl9zaS5wZGYiKSwKICAgICAgIGZvcmVzdF9jN19zaV9vcywKICAgICAgIHdpZHRoID0gOSwgaGVpZ2h0ID0gNCwgdW5pdHMgPSAiaW4iLAogICAgICAgZGV2aWNlID0gInBkZiIpCmBgYAoKClByaW50IHNlc3Npb24gaW5mbwoKYGBge3J9CnNlc3Npb25JbmZvKCkKYGBg